//
//  TableEnable.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/5/24.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import UIKit
import Then
import RxSwift
import RxDataSources

public enum ScrollViewRefreshEnum { case none, header, footer, all }

private struct AssociateKeys {
    static var table: Void?
    // 也可以直接这样写
    // static var disablePopGesture = "disablePopGesture"
}

// MARK: - table enable
public protocol TableEnableProtocol : BindKeyProtocol { }


// MARK: - 添加一个 table view 属性
public extension TableEnableProtocol {
    
    var tableView: UITableView {
        get {
            return associatedObject(forKey: &AssociateKeys.table, default: tableV(), ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.table, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    @discardableResult
    private func tableV() -> UITableView {
        tableView = UITableView.init().then {
            $0.backgroundColor = .white
            $0.estimatedRowHeight = 44.0
            
            $0.estimatedSectionHeaderHeight = 0.0
            $0.estimatedSectionFooterHeight = 0.0

            $0.tableFooterView = UIView.init();
            $0.separatorStyle = .none;

            $0.showsVerticalScrollIndicator = false
            $0.showsHorizontalScrollIndicator = false
        
            if #available(iOS 15.0, *) {
                $0.sectionHeaderTopPadding = 0
            }
            
            $0.contentInsetAdjustmentBehavior = .never
        }
        return tableView
    }
}

// MARK: - 绑定 viewmodel
extension TableEnableProtocol {
    
    func bindVM(_ vm: TableViewModelProtocol, bag: DisposeBag, refreshConfig config: ScrollViewRefreshEnum = .none) {
        
        /// 初始化结束
        vm.initDown()
        
        /// tableview 获取
        let tv = tableView
        
        /// tableview 数据源
        let dataSource: RxTableViewSectionedReloadDataSource = vm.configDataSource()
        
        /// 防抖节流
        vm.sectionsSubject.debounce(.milliseconds(300), scheduler: MainScheduler.instance).bind(to: tv.rx.items(dataSource: dataSource)).disposed(by: bag)
        
        vm.reloadSubject.filter { _ in
            vm.isRefreshing = true
            return true
        }.debounce(.microseconds(300), scheduler: MainScheduler.instance).subscribe(onNext: { [weak self] val in
            vm.isRefreshing = false
            self?.tableView.reloadData()
        }).disposed(by: bag)
        
        /// 固定时间刷新节流
//        vm.sectionsSubject.throttle(.milliseconds(300), latest: true, scheduler: MainScheduler.instance).bind(to: tv.rx.items(dataSource: dataSource)).disposed(by: bag)
        
        /// 绑定key
        vm.bindKey(bag)
        /// 绑定父类key  父类是tableview的持有对象（一般我contoller或者view）
        vm.parentKey = bindKey()
        
        // 部分已写服务
        if let vc = self as? UIViewController {
            vm.configServicBlock(bag: bag) { [weak vc] service in
                switch service {
                case .controller:
                    return self
                case .table:
                    return tv
                case .view:
                    return vc?.view
                case .all:
                    return (vc, vc?.view, tv)
                case .reloadTable:
                    vm.reloadTable()
                    return nil
                case .endEdit:
                    vc?.view.endEditing(true)
                    tv.endEditing(true)
                    return nil
                }
            }
        }
        
        /// delegate 代理已实现的话 设置代理
        if let delegate = vm as? UITableViewDelegate {
            tv.rx.setDelegate(delegate).disposed(by: bag)
        }
        
        // 执行配置结束 viewmodel的开始方法
        vm.configDown()
        
    }
    
}

// MARK: - table for view controller
public extension TableEnableProtocol where Self : UIViewController {
    
    /// 绑定tableview
    /// - Parameter edges: 边距
    func configTable(_ edges: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -Screen.bottomBarHeight, right: 0)) {
        bgColor(.white)
        view.addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalTo(view).inset(edges)
        }
    }
 
}

// MARK: - table for view
public extension TableEnableProtocol where Self : UIView {
    
    /// 绑定tableview
    /// - Parameter edges: 边距
    func configTable(_ edges: UIEdgeInsets = UIEdgeInsets.zero) {
        addSubview(tableView)
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(edges)
        }
    }
    
}


// MARK: - table for all
// 不需要下拉上拉 直接 配置table
public extension TableEnableProtocol {
    
    /// 配置tableview
    /// - Parameters:
    ///   - vm: viewmodel
    ///   - disposeBag: 销毁包
    ///   - config: 刷新配置
    func configAll(_ vm: TableViewModelProtocol, disposeBag: DisposeBag, edges: UIEdgeInsets = UIEdgeInsets.zero) {
        /// 配置table
        if let vc = self as? (UIViewController & TableEnableProtocol) {
            vc.configTable(edges)
        }else
        if let v = self as? (UIView & TableEnableProtocol) {
            v.configTable(edges)
        }
        
        /// 绑定key 并且添加通知
        bindKey(disposeBag)
        
        /// 绑定view model
        bindVM(vm, bag: disposeBag)
        
        /// rx 来自 public extension Refreshable where Self: NSObject & TableEnableProtocol
        rx.tapEmptyButton(tableView) { _ in
            vm.refresh()
        }
        
    }
    
}

// 下拉上拉 直接 配置table
public extension TableEnableProtocol where Self: Refreshable {
    
    /// 配置tableview
    /// - Parameters:
    ///   - vm: viewmodel
    ///   - disposeBag: 销毁包
    ///   - config: 刷新配置
    func configAll<T: RefreshControllable & TableViewModelProtocol >(_ vm: T, disposeBag: DisposeBag, refreshConfig config: ScrollViewRefreshEnum = .none, edges: UIEdgeInsets = UIEdgeInsets.zero) {
        /// 配置table
        self.configAll(vm, disposeBag: disposeBag, edges: edges)
        self.rx.updateRefresh(vm, scrollview: tableView, bag: disposeBag, refreshConfig: config)
    }
}

// MARK: - 配置上拉下拉
public extension Refreshable where Self: TableEnableProtocol {
    func updateRefresh<T: RefreshControllable & TableViewModelProtocol >(_ vm: T, bag: DisposeBag, refreshConfig config: ScrollViewRefreshEnum) {
        
//        self.rx.refresh(vm, tableView).subscribe(onNext: {
//            switch $0 {
//            case .header:
//                vm.refresh()
//            case .footer:
//                vm.pull()
//            }
//        }).disposed(by: bag)
    
        switch config {
        case .none:
            vm.rx.refreshStatus.onNext(.hiddenHeader)
            vm.rx.refreshStatus.onNext(.hiddenFooter)
        case .header:
            vm.rx.refreshStatus.onNext(.hiddenFooter)
        case .footer:
            vm.rx.refreshStatus.onNext(.hiddenHeader)
        case .all: break
        }
        
    }
}
